package com.biubiux2.handler;

import com.biubiux2.message.MessageType;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;

import java.util.LinkedList;

/**
 * @author noexcs
 * @since 8/10/2022 2:28 AM
 */
public class MessageSynchronousHandler extends ChannelDuplexHandler {

    private int latestSynchronousMsgId = 0;

    private boolean needWait = false;

    private LinkedList<Object> cachedMsgList = new LinkedList<>();

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

        ByteBuf byteBuf = (ByteBuf) msg;
        int type = byteBuf.readInt();
        if (MessageType.isSynchronousResponse(type)) {
            int msgId = byteBuf.readInt();
            if (latestSynchronousMsgId == msgId) {
                needWait = false;
                if (cachedMsgList.isEmpty()) {
                    ctx.channel().writeAndFlush(msg);
                }
            }
        }
        ((ByteBuf) msg).resetReaderIndex();
        super.channelRead(ctx, msg);
    }

    @Override
    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
        ByteBuf byteBuf = (ByteBuf) msg;
        int type = byteBuf.readInt();
        if (MessageType.isSynchronous(type)) {
            if (needWait) {
                cachedMsgList.addLast(msg);
            } else {
                int msgId = byteBuf.readInt();
                latestSynchronousMsgId = msgId;
                needWait = true;
                byteBuf.resetReaderIndex();
                super.write(ctx, msg, promise);
            }
        } else {
            byteBuf.resetReaderIndex();
            super.write(ctx, msg, promise);
        }
    }
}
